/**
 * 
 */
package due.pc.pcshoot.control;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.handler.timer.ITimerCallback;
import org.anddev.andengine.engine.handler.timer.TimerHandler;
import org.anddev.andengine.entity.scene.CameraScene;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.text.ChangeableText;
import org.anddev.andengine.entity.util.FPSCounter;
import org.anddev.andengine.opengl.font.StrokeFont;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;

import due.pc.pcshoot.MainActivity;
import due.pc.pcshoot.entity.Canon;
import due.pc.pcshoot.entity.IEnemy;
import due.pc.pcshoot.gamelogic.ArrowsLogicHandler;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.util.Log;

/**
 * @author manhhung.vu
 *
 */
public class OnScreenLogger extends CameraScene
{
	//===============================================================/
	//Constants
	//===============================================================/
	public static final int FONT_SIZE = 32;
	
	public static final int FPSTEXT_X = 0;
	public static final int FPSTEXT_Y = 40;
	public static final int ELAPSEDSECONDSTEXT_X = 0;
	public static final int ELAPSEDSECONDSTEXT_Y = 0;
	
	public static final int SCORESTEXT_X = 440;
	public static final int SCORESTEXT_Y = 0;
	
	public static final int LIVESTEXT_X = 440;
	public static final int LIVESTEXT_Y = 40;
	
	public static final int SHOTTEXT_X = 440;
	public static final int SHOTTEXT_Y = MainActivity.CAMERA_HEIGHT - 40;
	
	public static final int KILLTEXT_X = 630;
	public static final int KILLTEXT_Y = MainActivity.CAMERA_HEIGHT - 40;
	
	public static final int LANDTEXT_X = 0;
	public static final int LANDTEXT_Y = MainActivity.CAMERA_HEIGHT - 40;
	
	//===============================================================/
	//Fields
	//===============================================================/
	private Engine mEngine;
	private float mCameraCenterX, mCameraCenterY, mCameraWidth, mCameraHeight;
	
	private FPSCounter mFPSCounter = new FPSCounter();
	
	private Texture mFontTexture;
	private StrokeFont mStrokeFont;
	
	private ChangeableText mFPSText, mElapsedSecondsText;
	private ChangeableText mLivesText, mScoresText, mShotText;
	private ChangeableText mLandText, mKillText;
	
	private Arrow mArrowLeft, mArrowRight, mArrowTop, mArrowBottom;
	
	private Player mPlayer;
	private Canon mCanon;
	
	private int mLanded, mKilled;
	
	//===============================================================/
	//Constructors
	//===============================================================/
	/**
	 * Die Konstruktor dieser Klasse soll in Game::loadResources aufgerufen werden
	 */
	public OnScreenLogger(Engine pEngine, Context pContext) 
	{
		super(pEngine.getCamera());
		mEngine = pEngine;
		
		mCameraWidth = mCamera.getWidth();
		mCameraHeight = mCamera.getHeight();
		mCameraCenterX = mCameraWidth * 0.5f;
		mCameraCenterY = mCameraHeight * 0.5f;
		
		mEngine.registerUpdateHandler(mFPSCounter);
		
		mFontTexture = new Texture(256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		mStrokeFont = new StrokeFont(mFontTexture, Typeface.create(Typeface.DEFAULT, Typeface.BOLD), FONT_SIZE, true, Color.BLACK, 2, Color.WHITE);
		mEngine.getTextureManager().loadTextures(mFontTexture);
		mEngine.getFontManager().loadFonts(mStrokeFont);
		
		mFPSText = new ChangeableText(FPSTEXT_X, FPSTEXT_Y, mStrokeFont, "FPS:", "FPS: XXXXXXX".length());
		mFPSText.setAlpha(0.2f);
		attachChild(mFPSText);
		
		mElapsedSecondsText = new ChangeableText(ELAPSEDSECONDSTEXT_X, ELAPSEDSECONDSTEXT_Y, mStrokeFont, "Time:", "Time: XXXXXX".length());
		mElapsedSecondsText.setAlpha(0.2f);
		attachChild(mElapsedSecondsText);
		
		mLivesText = new ChangeableText(LIVESTEXT_X, LIVESTEXT_Y, mStrokeFont, "Live:", "Lives: XXXXXXX".length());
		mLivesText.setAlpha(0.2f);
		attachChild(mLivesText);
		
		mScoresText = new ChangeableText(SCORESTEXT_X, SCORESTEXT_Y, mStrokeFont, "Score:", "Score: XXXXXX".length());
		mScoresText.setAlpha(0.2f);
		attachChild(mScoresText);
		
		mShotText = new ChangeableText(SHOTTEXT_X, SHOTTEXT_X, mStrokeFont, "Shot:", "Shot: XXXXXX".length());
		mShotText.setAlpha(0.2f);
		attachChild(mShotText);
		
		mLandText = new ChangeableText(LANDTEXT_X, LANDTEXT_Y, mStrokeFont, "Landed:", "Landed: XXXXXX".length());
		mLandText.setAlpha(0.2f);
		attachChild(mLandText);
		
		mKillText = new ChangeableText(KILLTEXT_X, KILLTEXT_Y, mStrokeFont, "Killed:", "Killed: XXXXXX".length());
		mKillText.setAlpha(0.2f);
		attachChild(mKillText);
		
		registerUpdateHandler(new TimerHandler(0.1f, true,
				new ITimerCallback() {
					@Override
					public void onTimePassed(TimerHandler pTimerHandler) 
					{
						mElapsedSecondsText.setText("Time: " + mEngine.getSecondsElapsedTotal());
						mFPSText.setText("FPS: " + mFPSCounter.getFPS());
						
						mScoresText.setText("Score: " + mPlayer.getScores());
						mLivesText.setText("Live: " + mPlayer.getLives());
						mShotText.setText("Shot: " + mCanon.getShotAmong());
						
						mLandText.setText("Landed: " + mLanded);
						mKillText.setText("Killed: " + mKilled);
					}
				}));
		
		
		mArrowLeft = Arrow.createArrow(0, mCameraCenterY - Arrow.ARROW_HEIGHT * 0.5f, Arrow.DIRECTION_LEFT, pEngine, pContext);
		mArrowRight = Arrow.createArrow(mCameraWidth - Arrow.ARROW_WIDTH, mCameraCenterY - Arrow.ARROW_HEIGHT * 0.5f, Arrow.DIRECTION_RIGHT, pEngine, pContext);
		mArrowTop = Arrow.createArrow(mCameraCenterX - Arrow.ARROW_WIDTH * 0.5f, 0, Arrow.DIRECTION_TOP, pEngine, pContext);
		mArrowBottom = Arrow.createArrow(mCameraCenterX - Arrow.ARROW_WIDTH * 0.5f, mCameraHeight - Arrow.ARROW_HEIGHT, Arrow.DIRECTION_BOTTOM, pEngine, pContext);

		setBackgroundEnabled(false);
	}
	
	//===============================================================/
	//Inherited Methods
	//===============================================================/
	
	
	//===============================================================/
	//Methods
	//===============================================================/
	public void registerOnParent(Scene pParentScene) 
	{
		pParentScene.setChildScene(this);
	}
	
	public void applyFollowedObjects(Player pPlayer, Canon pCanon) 
	{
		mPlayer = pPlayer;
		mCanon = pCanon;
	}
	
	public void applyArrowsLogicHandler(IEnemy[] pEnemies)
	{
		new ArrowsLogicHandler(
				new Arrow[]{mArrowLeft, mArrowRight, mArrowTop, mArrowBottom},
				pEnemies, mCamera, this);
	}
	
	//===============================================================/
	//Getters & Setters
	//===============================================================/
	public int getKilled() {
		return mKilled;
	}
	
	public void setKilled(int pKilled) {
		this.mKilled = pKilled;
	}
	
	public int getLanded() {
		return mLanded;
	}
	
	public void setLanded(int pLanded) {
		this.mLanded = pLanded;
	}
}
